class MagicBox04<T:Human>(item: T) {
    var available = false
    private var subject: T = item
    fun fetch(): T? {
        return subject.takeIf { available }
    }

    fun <R> fetch(subjectModFunction: (T) -> R): R? {
        return subjectModFunction(subject).takeIf { available }
    }
}

open class Human(val age: Int)
class Boy04(val name: String, age: Int) : Human(age)
class Man01(val name: String, age: Int) : Human(age)
class Dog04(val weight: Int)

fun main() {
    val magicBox: MagicBox04<Boy04> = MagicBox04(Boy04("jack", 80))
    //val magicBox1: MagicBox04<Dog04> = MagicBox04(Dog04(90))
    magicBox.available = true
    magicBox.fetch()?.run {
        println("you find $name")
    }

    val man = magicBox.fetch {
        Man01(it.name, it.age.plus(15))
    }
}